package cn.ant.controller;

import cn.ant.annotation.AopControllerLog;
import cn.ant.entity.FlowCompleteParam;
import cn.ant.entity.FlowRollbackParams;
import cn.ant.entity.FlowStartParams;
import cn.ant.entity.FlowTaskEntity;
import cn.ant.service.FlowManagerService;
import cn.ant.service.FlowParamTransmitService;
import cn.hutool.core.thread.ThreadUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

@Controller
@RequestMapping(value = "flowManager")
@AopControllerLog
@Slf4j
public class FlowManagerController {
    @Autowired
    private FlowManagerService flowManagerService;

    @Autowired
    private FlowParamTransmitService flowParamTransmitService;

    /**
     * 部署流程
     *
     * @param flowFileName
     * @return
     */
    @GetMapping("/deployFlow")
    @ResponseBody
    public String deployFlow(String flowFileName) {
        return flowManagerService.deployFlow(flowFileName);
    }

    /**
     * 启动流程
     *
     * @param flowStartParams
     * @return
     */
    @PostMapping("/startFlow")
    @ResponseBody
    public String startFlow(@RequestBody FlowStartParams flowStartParams) {
        return flowManagerService.startFlow(flowStartParams);
    }

    /**
     * 通过任务Id完成任务
     *
     * @param taskId
     * @return
     */
    @GetMapping("/completeTaskByTaskId")
    @ResponseBody
    public String completeTaskByTaskId(String taskId) {
        return flowManagerService.completeTaskByTaskId(taskId);
    }

    /**
     * 通过任务Id完成任务
     *
     * @param flowCompleteParam
     * @return
     */
    @PostMapping("/completeTaskParam")
    @ResponseBody
    public void completeTaskParam(@RequestBody FlowCompleteParam flowCompleteParam) {
        flowParamTransmitService.completeTaskParam(flowCompleteParam.getTaskId(), flowCompleteParam.getMap());
    }

    /**
     * 通过任务Id完成任务
     *
     * @param flowCompleteParam
     * @return
     */
    @PostMapping("/completeTaskParamChooseThree")
    @ResponseBody
    public void completeTaskParamChooseThree(@RequestBody FlowCompleteParam flowCompleteParam) {
        flowParamTransmitService.completeTaskParamChooseThree(flowCompleteParam.getTaskId(), flowCompleteParam.getMap(), flowCompleteParam.getFlag());
    }


    /**
     * 通过任务Id查询当前任务的参数
     *
     * @param taskId
     * @return
     */
    @GetMapping("/getCompleteTaskParam")
    @ResponseBody
    public Map<String, Object> getCompleteTaskParam(String taskId) {
        return flowParamTransmitService.getCompleteTaskParam(taskId);
    }

    /**
     * 通过任务Id查询当前任务的参数
     *
     * @param flowCompleteParam
     * @return
     */
    @PostMapping("/setCompleteTaskParam")
    @ResponseBody
    public void setCompleteTaskParam(@RequestBody FlowCompleteParam flowCompleteParam) {
        flowParamTransmitService.setCompleteTaskParam(flowCompleteParam.getTaskId(), flowCompleteParam.getMap());
    }

    @PostMapping("/rollBackSingle")
    @ResponseBody
    public void rollBackSingle(@RequestBody FlowRollbackParams flowRollbackParams) {
        flowManagerService.rollBackSingle(flowRollbackParams);
    }

    /**
     * 获取正在执行的任务列表信息
     *
     * @return
     */
    @GetMapping("/getRunningTaskList")
    @ResponseBody
    public JSON getRunningTaskList() {
        List<FlowTaskEntity> taskList = flowManagerService.getRunningTaskList();
        return JSONUtil.parse(taskList);
    }

    /**
     * 批量处理 通过流程id
     *
     * @param processIds
     */
    @PostMapping("/batchTaskByFlowId")
    @ResponseBody
    public void batchTaskByFlowId(@RequestBody List<String> processIds) {
        flowManagerService.batchTaskByFlowId(processIds);
        log.info("controller batchTaskByFlowId finish");
    }

    /**
     * 批量处理作业
     *
     * @param processIds
     */
    @PostMapping("/batchJobByFlowId")
    @ResponseBody
    public void batchJobByFlowId(@RequestBody List<String> processIds) {
        flowManagerService.batchJobByFlowId(processIds);
    }

    /**
     * 获取流程图
     *
     * @param processInstanceId
     * @return
     */
    @GetMapping("/getFlowImage")
    @ResponseBody
    public void getFlowImage(@RequestParam("processInstanceId") String processInstanceId, HttpServletResponse httpServletResponse) throws Exception {
        byte[] flowImage = flowManagerService.getFlowImage(processInstanceId);
        httpServletResponse.getOutputStream().write(flowImage);
    }

    @GetMapping("/getAsynData")
    @ResponseBody
    public FlowRollbackParams getAsynData() {
        FlowRollbackParams flowRollbackParams = new FlowRollbackParams();
        flowRollbackParams.setFlowCurrentTaskDefinitionId("同步数据");
        CompletableFuture.runAsync(() -> {
            ThreadUtil.sleep(new Random().nextDouble(), TimeUnit.SECONDS);
            flowRollbackParams.setFlowCurrentTaskDefinitionId("异步数据");
        });
        return flowRollbackParams;
    }

    @GetMapping("/addTask")
    @ResponseBody
    public String addTask(String processInstanceId) {
        return flowManagerService.addTask(processInstanceId);
    }

    @GetMapping("/addSubTask")
    @ResponseBody
    public String addSubTask(String processInstanceId) {
        return JSONUtil.toJsonStr(flowManagerService.addSubTask(processInstanceId));
    }

    @GetMapping("/addSubTaskByProcessDefinition")
    @ResponseBody
    public String addSubTaskByProcessDefinition(String processInstanceId, String processDefinitionKey, String taskDefinitionKey) {
        return JSONUtil.toJsonStr(flowManagerService.addSubTaskByProcessDefinition(processInstanceId, processDefinitionKey, taskDefinitionKey));
    }

    /**
     * 挂起流程
     *
     * @param processInstanceId
     */
    @GetMapping("/hangUp")
    @ResponseBody
    public void hangUp(String processInstanceId) {
        flowManagerService.hangUp(processInstanceId);
    }

    /**
     * 激活
     *
     * @param processInstanceId
     */
    @GetMapping("/activate")
    @ResponseBody
    public void activate(String processInstanceId) {
        flowManagerService.activate(processInstanceId);
    }
}
